
package com.bnzj.cloud.business.core.web;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import com.bnzj.cloud.business.core.persistence.entity.SysRoleUser;
import com.bnzj.cloud.business.core.persistence.entity.SysUser;
import com.bnzj.cloud.business.core.service.SysRoleUserService;
import com.bnzj.cloud.business.core.service.SysUserService;
import com.bnzj.cloud.business.core.vo.RoleUserDeptVo;
import com.bnzj.cloud.util.AliyunIdCardUtil;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.bnzj.core.action.ActionType;
import com.bnzj.core.action.annotation.Action;
import com.bnzj.core.exception.BusinessException;
import com.bnzj.core.persistence.query.CompareExpression;
import com.bnzj.core.persistence.query.CompareType;
import com.bnzj.core.persistence.query.IExpression;
import com.bnzj.core.persistence.query.QueryHelpBean;
import com.bnzj.core.persistence.util.EntityUtils;
import com.bnzj.core.rest.CurrentUserService;
import com.bnzj.core.rest.ResponseResult;
import com.bnzj.core.rest.ResultCode;
import com.bnzj.core.rest.UserInfo;
import com.bnzj.core.util.SpringUtils;
import com.bnzj.core.webmvc.util.WebMvcUtils;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;

/**
 * @author Barry
 * @createDate 2020/2/17
 * @description
 */
@Tag(name = "用户", description = "用户管理")
@RestController
@RequestMapping("/system/user")
public class SysUserController {

    @Autowired
    private CurrentUserService gatewayCurrentUserService;

    @Autowired
    private SysRoleUserService sysRoleUserService;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Value("${bnzj.security.default-password?:987123}")
    private String defaultPassword;

    /**
     * @param request
     * @return com.bnzj.core.rest.ResponseResult<org.springframework.data.domain.Page>
     * @depict 分页查询
     * @auth Barry
     * @createDate 2020/2/17
     * @updateAuthOrOther
     */
    @Operation(summary = "分页查询", description = "分页查询", parameters = {
            @Parameter(name = "deptId", description = "部门id", allowEmptyValue = true, allowReserved = true, schema = @Schema(type = "long", description = "部门id")),
            @Parameter(name = "limit", description = "分页大小", allowEmptyValue = true, allowReserved = true, schema = @Schema(type = "int", description = "分页大小")),
            @Parameter(name = "offset", description = "页码", allowEmptyValue = true, allowReserved = true, schema = @Schema(type = "int", description = "页码")),
            @Parameter(name = "personnel", description = "在职状态(1在职，0离职)", allowEmptyValue = true, allowReserved = true, schema = @Schema(implementation = Integer.class, description = "在职状态(1在职，0离职")),
            @Parameter(name = "type", description = "用户类型A 内部用户B供应商用户", allowEmptyValue = true, allowReserved = true, schema = @Schema(implementation = String.class, description = "用户类型A 内部用户B供应商用户")),
            @Parameter(name = "enabled", description = "默认查启用 值为1 、启用0禁用", allowEmptyValue = true, allowReserved = true, schema = @Schema(implementation = Integer.class, description = "默认查启用 值为1 、启用0禁用")),
            @Parameter(name = "keyWord", description = "根据中英文名/员工编号/手机/邮箱模糊查询", allowEmptyValue = true, allowReserved = true, schema = @Schema(implementation = String.class, description = "根据中英文名/员工编号/手机/邮箱模糊查询")),
    })
    @PostMapping(value = "/page")
    public ResponseResult<Page<SysUser>> getUserPage(HttpServletRequest request,
                                                     @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "屏蔽用户ids", content = {@Content(array = @ArraySchema(schema = @Schema(type = "Long", implementation = Long.class, description = "用户id")))})
                                                     @RequestBody(required = false) List<Long> noIds) {
        Pageable pageable = WebMvcUtils.initPage(request, Sort.by(Sort.Direction.DESC, "u.create_time"));
        QueryHelpBean queryHelpBean = SysUserService.getQueryHelpBean();
        queryHelpBean.setPageable(pageable);
        IExpression deptIdCondition = CompareExpression.build("u.dept_id", CompareType.equal, request.getParameter("deptId"));
        String personnelStr = request.getParameter("personnel");
        if(personnelStr != null) {
            int personnel = "0".equals(personnelStr) || Boolean.FALSE.toString().equals(personnelStr) ? 0 : 1;
            IExpression personnelCondition = CompareExpression.build("u.personnel", CompareType.equal, personnel);
            queryHelpBean.addWhere(personnelCondition);
        }
        IExpression typeCondition = CompareExpression.build("u.type", CompareType.equal, request.getParameter("type"));
        if (!CollectionUtils.isEmpty(noIds)) {
            IExpression notIdsCondition = CompareExpression.build("u.id", CompareType.notIn, noIds);
            queryHelpBean.addWhere(notIdsCondition);
        }
        String enabledStr = request.getParameter("enabled");
        if(enabledStr != null) {
            int enabled = "0".equals(enabledStr) || Boolean.FALSE.toString().equals(enabledStr) ? 0 : 1;
            IExpression enableCondition = CompareExpression.build("u.enabled", CompareType.equal, enabled);
            queryHelpBean.addWhere(enableCondition);
        }
        String keyWord = request.getParameter("keyWord");
        IExpression orCondition1 = CompareExpression.build("u.cname", CompareType.like, keyWord);
        IExpression orCondition2 = CompareExpression.build("u.account", CompareType.like, keyWord);
        IExpression orCondition4 = CompareExpression.build("u.email", CompareType.like, keyWord);
        IExpression orCondition5 = CompareExpression.build("u.phone", CompareType.like, keyWord);
        IExpression orCondition6 = CompareExpression.build("u.ename", CompareType.like, keyWord);
        IExpression orConditions = orCondition1.or(orCondition2, orCondition4, orCondition5, orCondition6);
        queryHelpBean.addWhere(deptIdCondition, orConditions, typeCondition);
        Page<SysUser> all1 = sysUserService.findAll(queryHelpBean);
        return ResponseResult.success(all1);
    }


    @Operation(summary = "根据id查询")
    @GetMapping("/one/{id}")
    public ResponseResult<?> getById(@Parameter(in = ParameterIn.PATH, name = "id", description = "主键", required = true) @PathVariable("id") Long id) {
        Optional<SysUser> optional = sysUserService.findById(id);
        return ResponseResult.success(optional.orElse(null));
    }

    @Operation(summary = "根据员工工号查询")
    @GetMapping("/{account}/info")
    public ResponseResult<SysUser> getUser(@PathVariable("account") String account) {
        SysUser user = sysUserService.findByAccount(account);
        if (ObjectUtils.isEmpty(user)) {
            throw new BusinessException(ResultCode.getResultCode(ResultCode.RESOURCE_NOT_EXIST));
        }
        return ResponseResult.success(user);
    }

    @Operation(summary = "获取当前登录用户")
    @GetMapping("/current-user/info")
    public ResponseResult<SysUser> getCurrentUser() {
        SysUser byAccount = sysUserService.findByAccount(gatewayCurrentUserService.getAccount());
//        byAccount.setRoleUserList(null);
//        byAccount.setDeprtment(null);
        return ResponseResult.success(byAccount);
    }

    @Operation(summary = "保存")
    @Action(descriprion = "用户保存",moduleName = "用户",operateType = ActionType.ADD_DATA)
    @PostMapping("/save")
    public ResponseResult<?> addUser(@RequestBody SysUser sysUser) {
        UserInfo userInfo = gatewayCurrentUserService.getUserInfo();
        EntityUtils.saveBefore(sysUser, userInfo.getAccount(), userInfo.getName());
        sysUser.setPassword(passwordEncoder.encode(defaultPassword));
        sysUserService.save(sysUser);
        return ResponseResult.success();
    }

    @Operation(summary = "实名制")
    @Action(descriprion = "实名制",moduleName = "用户",operateType = ActionType.ADD_DATA)
    @PostMapping("/realnameRegist")
    public ResponseResult<?> realnameRegist(@RequestBody Map<String,String> map) {
        String cname = map.get("cname");
        String phone = map.get("phone");
        String identity = map.get("identity");
        /*boolean res = AliyunIdCardUtil.verifyIdCard(identity, cname, phone);
        if(!res) {
            throw new BusinessException("实名制失败", ResultCode.BAD_REQUEST);
        } else {*/
            SysUser sysUser = sysUserService.findByAccount(gatewayCurrentUserService.getAccount());
            sysUser.setCname(cname);
            sysUser.setPhone(phone);
            sysUser.setIdentity(identity);
            sysUser.setIsRecord("是");
            sysUserService.save(sysUser);
        //}
        return ResponseResult.success();
    }

    @Operation(summary = "更新")
    @Action(descriprion = "用户更新",moduleName = "用户",operateType = ActionType.UPDATE_DATA)
    @PostMapping("/update")
    public ResponseResult<?> updateUser(@RequestBody SysUser user) {
        if (ObjectUtils.isEmpty(user.getId())) {
            throw new BusinessException("id不能为空！", ResultCode.BAD_REQUEST);
        }
        UserInfo userInfo = gatewayCurrentUserService.getUserInfo();
        EntityUtils.saveBefore(user, userInfo.getAccount(), userInfo.getName());
        sysUserService.save(user);
        return ResponseResult.success();
    }


    /**
     * 禁用
     *
     * @param
     * @return updateUserEnableById
     */
    @Operation(summary = "禁用")
    @Action(descriprion = "用户禁用",moduleName = "用户",operateType = ActionType.UPDATE_DATA)
    @PostMapping(value = {"/disable"})
    public ResponseResult<?> disabled(@RequestBody List<String> accountList) {
        sysUserService.disable(accountList);
        return ResponseResult.success();
    }


    @Operation(summary = "启用")
    @Action(descriprion = "用户启用",moduleName = "用户",operateType = ActionType.UPDATE_DATA)
    @PostMapping(value = {"/enabled/{id}/{status}"})
    public ResponseResult<?> updateUserEnableById(@Parameter(in = ParameterIn.PATH, description = "主键", required = true, name = "id") @PathVariable("id") Long id,
                                                  @Parameter(in = ParameterIn.PATH, description = "启用1禁用0", required = true, name = "status") @PathVariable("status") boolean status) {
        sysUserService.updateUserEnableById(id, status);
        return ResponseResult.success();
    }


    @Operation(summary = "获取所有员工工号")
    @PostMapping(value = {"/all/account"})
    public ResponseResult<Set<String>> findAllAccount() {
        Set<String> allAccount = sysUserService.findAllAccount();
        return ResponseResult.success(allAccount);
    }


    @Operation(summary = "获取所有启用员工工号")
    @PostMapping(value = {"/enable/account"})
    public ResponseResult<Set<String>> findAllAccountByEnabled() {
        Set<String> allAccount = sysUserService.findAllAccountByEnabled();
        return ResponseResult.success(allAccount);
    }

    /**
     * @param list
     * @return com.bnzj.core.rest.ResponseResult
     * @depict 给用户授权角色
     * @auth Barry
     * @createDate 2020/2/20
     * @updateAuthOrOther
     */
    @Operation(summary = "用户授权角色", description = "用户授权角色")
    @PostMapping(value = {"/permission/{userId}"})
    public ResponseResult<?> permissionAssignment(@RequestBody List<SysRoleUser> list,
                                                  @Parameter(name = "roleId", description = "用户id",
                                                          schema = @Schema(name = "userId", type = "long")) @PathVariable(value = "userId",
                                                          required = true) Long userId) {
        SysRoleUserService sysRoleUserService = SpringUtils.get(SysRoleUserService.class);
        sysRoleUserService.portionRole(list, userId);
        return ResponseResult.success();
    }


    /**
     * @param
     * @return com.bnzj.core.rest.ResponseResult
     * @depict 给用户授权角色和部门
     * @auth Barry
     * @createDate 2020/2/20
     * @updateAuthOrOther
     */
    @Operation(summary = "用户授权角色和部门", description = "用户授权角色和部门")
    @PostMapping(value = {"/permission"})
    public ResponseResult<?> permissionAssignmentRoleDept(@RequestBody List<RoleUserDeptVo> roleUserDeptVos) {
        SysRoleUserService sysRoleUserService = SpringUtils.get(SysRoleUserService.class);
        UserInfo userInfo = gatewayCurrentUserService.getUserInfo();
        sysRoleUserService.portionRoleDept(roleUserDeptVos,userInfo);
        return ResponseResult.success();
    }

    @Operation(summary = "获取该用户下所有角色id", description = "根据主键获取该用户下所有角色")
    @GetMapping("/roles/{id}")
    public ResponseResult<List<Long>> getRoleIdsByUserId(@Parameter(in = ParameterIn.PATH, name = "id", required = true,
            description = "主键") @PathVariable("id") Long userId) {
        List<Long> coll = sysRoleUserService.getRoleIdsByUserId(userId);
        return ResponseResult.success(coll);
    }
}
















